package com.yupao.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupao.common.BaseResponse;
import com.yupao.common.ResultUtils;
import com.yupao.exception.BusinessException;
import com.yupao.model.dto.*;
import com.yupao.model.entity.Team;
import com.yupao.model.entity.UserTeam;
import com.yupao.model.enums.ErrorCode;
import com.yupao.model.vo.LoginUserVO;
import com.yupao.model.vo.UserTeamVO;
import com.yupao.service.TeamService;
import com.yupao.service.UserService;
import com.yupao.service.UserTeamService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 队伍表 前端控制器
 * </p>
 *
 * @author beiji
 * @since 2024-09-22
 */
@RestController
@RequestMapping("/team")
@CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials="true")
public class TeamController {

    @Resource
    private TeamService teamService;
    @Resource
    private UserService userService;
    @Resource
    private UserTeamService userTeamService;

    /**
     * 添加队伍
     * @param team
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addTeam(@RequestBody TeamDTO team){
        if (ObjectUtils.isEmpty(team)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        LoginUserVO loginUser = userService.getLoginUser();
        Long teamId =  teamService.addTeam(team, loginUser);

        return ResultUtils.success(teamId);
    }

    /**
     *解散队伍
     * @param teamDeleteRequest
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteTeam(@RequestBody TeamDeleteRequest teamDeleteRequest){
        if (ObjectUtils.isEmpty(teamDeleteRequest)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Long teamId = teamDeleteRequest.getId();
        boolean result = teamService.deleteTeam(teamId);

        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }

        return ResultUtils.success(true);
    }

    /**
     * 修改队伍信息
     * @param teamUpdateRequest
     * @return
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateTeam(@RequestBody TeamUpdateRequest teamUpdateRequest){
        if (ObjectUtils.isEmpty(teamUpdateRequest)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        boolean result = teamService.updateTeam(teamUpdateRequest);

        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }

        return ResultUtils.success(true);
    }

    /**
     * 查询队伍信息
     * @param id
     * @return
     */
    @GetMapping("/get")
    public BaseResponse<Team> getTeamById(long id){
        if (id < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Team team = teamService.getById(id);

        if (ObjectUtils.isEmpty(team)) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }

        return ResultUtils.success(team);
    }

    /**
     * 用户加入队伍
     * @param teamJoinRequest
     * @return
     */
    @PostMapping("/join")
    public BaseResponse<Boolean> joinTeam(@RequestBody TeamJoinRequest teamJoinRequest){
        if (ObjectUtils.isEmpty((teamJoinRequest))) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Boolean result = teamService.joinTeam(teamJoinRequest);

        return ResultUtils.success(result);
    }

    /**
     * 查询队伍列表
     * @param teamDTO
     * @return
     */
    @GetMapping("/list")
    public BaseResponse<List<UserTeamVO>> listTeams(TeamDTO teamDTO){
        if (ObjectUtils.isEmpty(teamDTO)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        List<UserTeamVO> userTeamVOList = teamService.listTeams(teamDTO);
        Set<Long> teamIdList = Collections.emptySet();
        try {
            //条件一：登录用户id
            LoginUserVO loginUser = userService.getLoginUser();
            Long userId = loginUser.getId();
            //条件二：所有队伍id
            teamIdList = userTeamVOList.stream().map(UserTeamVO::getId).collect(Collectors.toSet());
            //在队伍用户表中搜索该用户加入的队伍中的id
            Set<Long> hasJoinTeamId = userTeamService.lambdaQuery()
                    .eq(UserTeam::getUserId, userId)
                    .in(UserTeam::getTeamId, teamIdList)
                    .list().stream()
                    .map(UserTeam::getTeamId).collect(Collectors.toSet());

            //判断是否加入该队伍
            userTeamVOList.forEach(
                    userTeamVO -> {
                        Long teamVOId = userTeamVO.getId();
                        if (hasJoinTeamId.contains(teamVOId)) {
                            userTeamVO.setHasJoin(true);
                        }
                    }
            );
        } catch (Exception ignored) {

        }

        if (teamIdList.size() != 0) {
            //添加队伍人数
            List<UserTeam> userTeamList = userTeamService.lambdaQuery()
                    .in(UserTeam::getTeamId, teamIdList)
                    .list();
            //根据队伍id进行分组
            Map<Long, List<UserTeam>> groupingTeamById = userTeamList.stream()
                    .collect(Collectors.groupingBy(UserTeam::getTeamId));
            //填充加入人数字段
            userTeamVOList.forEach( userTeamVO -> {
                userTeamVO.setJoinTeamNum(groupingTeamById.getOrDefault(userTeamVO.getId(), new ArrayList<>()).size());
            });
        }

        return ResultUtils.success(userTeamVOList);

    }

    /**
     * 查看我创建的队伍
     * @return
     */
    @GetMapping("/list/my/create")
    public BaseResponse<List<UserTeamVO>> listMyCreateTeams(){

        List<UserTeamVO> userTeamVOList = teamService.listMyTeams();
        //条件二：所有队伍id
        Set<Long> teamIdList = userTeamVOList.stream().map(UserTeamVO::getId).collect(Collectors.toSet());
        try {
            //条件一：登录用户id
            LoginUserVO loginUser = userService.getLoginUser();
            Long userId = loginUser.getId();
            //在队伍用户表中搜索该用户加入的队伍中的id
            Set<Long> hasJoinTeamId = userTeamService.lambdaQuery()
                    .eq(UserTeam::getUserId, userId)
                    .in(UserTeam::getTeamId, teamIdList)
                    .list().stream()
                    .map(UserTeam::getTeamId).collect(Collectors.toSet());

            //判断是否加入该队伍
            userTeamVOList.forEach(
                    userTeamVO -> {
                        Long teamVOId = userTeamVO.getId();
                        if (hasJoinTeamId.contains(teamVOId)) {
                            userTeamVO.setHasJoin(true);
                        }
                    }
            );
        } catch (Exception ignored) {

        }

        if (teamIdList.size() != 0) {
            //添加队伍人数
            List<UserTeam> userTeamList = userTeamService.lambdaQuery()
                    .in(UserTeam::getTeamId, teamIdList)
                    .list();
            //根据队伍id进行分组
            Map<Long, List<UserTeam>> groupingTeamById = userTeamList.stream()
                    .collect(Collectors.groupingBy(UserTeam::getTeamId));
            //填充加入人数字段
            userTeamVOList.forEach( userTeamVO -> {
                userTeamVO.setJoinTeamNum(groupingTeamById.getOrDefault(userTeamVO.getId(), new ArrayList<>()).size());
            });
        }

        return ResultUtils.success(userTeamVOList);
    }

    /**
     * 查看我加入的队伍
     * @return
     */
    @GetMapping("/list/my/join")
    public BaseResponse<List<UserTeamVO>> listMyJoinTeams(){

        List<UserTeamVO> userTeamVOList = teamService.listMyJoinTeams();
        //条件二：所有队伍id
        Set<Long> teamIdList =  teamIdList = userTeamVOList.stream().map(UserTeamVO::getId).collect(Collectors.toSet());
        try {
            //条件一：登录用户id
            LoginUserVO loginUser = userService.getLoginUser();
            Long userId = loginUser.getId();
            //在队伍用户表中搜索该用户加入的队伍中的id
            Set<Long> hasJoinTeamId = userTeamService.lambdaQuery()
                    .eq(UserTeam::getUserId, userId)
                    .in(UserTeam::getTeamId, teamIdList)
                    .list().stream()
                    .map(UserTeam::getTeamId).collect(Collectors.toSet());

            //判断是否加入该队伍
            userTeamVOList.forEach(
                    userTeamVO -> {
                        Long teamVOId = userTeamVO.getId();
                        if (hasJoinTeamId.contains(teamVOId)) {
                            userTeamVO.setHasJoin(true);
                        }
                    }
            );
        } catch (Exception ignored) {

        }


        if (teamIdList.size() != 0) {
            //添加队伍人数
            List<UserTeam> userTeamList = userTeamService.lambdaQuery()
                    .in(UserTeam::getTeamId, teamIdList)
                    .list();
            //根据队伍id进行分组
            Map<Long, List<UserTeam>> groupingTeamById = userTeamList.stream()
                    .collect(Collectors.groupingBy(UserTeam::getTeamId));
            //填充加入人数字段
            userTeamVOList.forEach( userTeamVO -> {
                userTeamVO.setJoinTeamNum(groupingTeamById.getOrDefault(userTeamVO.getId(), new ArrayList<>()).size());
            });
        }

        return ResultUtils.success(userTeamVOList);
    }

    /**
     * 分页查询用户
     * @param teamDTO
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<Team>> listTeamsByPage(@RequestBody TeamDTO teamDTO){
        if (ObjectUtils.isEmpty(teamDTO)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Team team = new Team();
        BeanUtils.copyProperties(teamDTO, team);

        Page<Team> page = new Page<>(teamDTO.getPageNum(), teamDTO.getPageSize());
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>(team);
        Page<Team> pageTeam = teamService.page(page, queryWrapper);

        return ResultUtils.success(pageTeam);
    }

    /**
     * 退出队伍
     * @param teamQuitRequest
     * @return
     */
    @PostMapping("/quit")
    public BaseResponse<Boolean> quitTeam(@RequestBody TeamQuitRequest teamQuitRequest){
        if (ObjectUtils.isEmpty(teamQuitRequest)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        boolean result = teamService.quitTeam(teamQuitRequest);

        return ResultUtils.success(result);
    }


}
